﻿using DoNet.ApiHttpClient;
using DoNet.Common.Helper;
using DoNet.WechatPay.Enums;
using DoNet.WechatPay.V2.Entitys;
using DoNet.WechatPay.V2.Entitys.Requests;
using DoNet.WechatPay.V2.Entitys.Results;
using Microsoft.Extensions.Logging;

namespace DoNet.WechatPay.V2
{
    /// <summary>
    /// 微信支付V2
    /// </summary>
    public class PayApiV2 : WechatMchBase
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="provider"></param>
        public PayApiV2(ILogger logger, IServiceProvider provider) : base(logger, provider)
        {

        }

        /// <summary>
        /// 统一下单
        /// 签名验证失败 返回null
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public IPayResultReturn? UnifiedOrder(IRequestBase request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.out_trade_no))
                        {
                            param.Add("out_trade_no", request.out_trade_no);
                        }
                        if (!string.IsNullOrWhiteSpace(request.body))
                        {
                            param.Add("body", request.body);
                        }
                        if (!string.IsNullOrWhiteSpace(request.device_info))
                        {
                            param.Add("device_info", request.device_info);
                        }
                        if (!string.IsNullOrWhiteSpace(request.detail))
                        {
                            param.Add("detail", request.detail);
                        }
                        if (!string.IsNullOrWhiteSpace(request.attach))
                        {
                            param.Add("attach", request.attach);
                        }
                        if (!string.IsNullOrWhiteSpace(request.fee_type))
                        {
                            param.Add("fee_type", request.fee_type);
                        }
                        param.Add("total_fee", request.total_fee);
                        if (!string.IsNullOrWhiteSpace(request.spbill_create_ip))
                        {
                            param.Add("spbill_create_ip", request.spbill_create_ip);
                        }
                        if (!string.IsNullOrWhiteSpace(request.time_start))
                        {
                            param.Add("time_start", request.time_start);
                        }
                        if (!string.IsNullOrWhiteSpace(request.time_expire))
                        {
                            param.Add("time_expire", request.time_expire);
                        }
                        if (!string.IsNullOrWhiteSpace(request.goods_tag))
                        {
                            param.Add("goods_tag", request.goods_tag);
                        }
                        if (!string.IsNullOrWhiteSpace(request.trade_type))
                        {
                            if (request.trade_type == "MICROPAY")
                            {
                                if (!string.IsNullOrWhiteSpace(request.auth_code))
                                {
                                    param.Add("auth_code", request.auth_code);
                                }
                            }
                            else
                            {
                                param.Add("trade_type", request.trade_type);

                                if (!string.IsNullOrWhiteSpace(request.notify_url))
                                {
                                    param.Add("notify_url", request.notify_url);
                                }
                                if (!string.IsNullOrWhiteSpace(request.openid))
                                {
                                    param.Add("openid", request.openid);
                                }
                                if (!string.IsNullOrWhiteSpace(request.sub_openid))
                                {
                                    param.Add("sub_openid", request.sub_openid);
                                }
                                if (request.trade_type != "APP")
                                {
                                    if (!string.IsNullOrWhiteSpace(request.product_id))
                                    {
                                        param.Add("product_id", request.product_id);
                                    }
                                }
                            }
                        }
                        if (!string.IsNullOrWhiteSpace(request.limit_pay))
                        {
                            param.Add("limit_pay", request.limit_pay);
                        }
                        if (!string.IsNullOrWhiteSpace(request.receipt))
                        {
                            param.Add("receipt", request.receipt);
                        }
                        if (!string.IsNullOrWhiteSpace(request.profit_sharing))
                        {
                            param.Add("profit_sharing", request.profit_sharing);
                        }
                        if (!string.IsNullOrWhiteSpace(request.scene_info))
                        {
                            param.Add("scene_info", request.scene_info);
                        }

                        if (request.trade_type != "MICROPAY")
                        {
                            string sign_type = "";
                            if (signType == PaySignType.HMACSHA256)
                            {
                                sign_type = "HMAC-SHA256";
                            }
                            else
                            {
                                sign_type = "MD5";
                            }
                            if (!string.IsNullOrWhiteSpace(sign_type))
                            {
                                param.Add("sign_type", sign_type);
                            }
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        string url = "pay/unifiedorder";
                        if (request.trade_type == "MICROPAY")
                        {
                            url = "pay/micropay";
                        }

                        var response = wechatMchService.SendRequest(HttpMethod.Post, url, param, "", null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var payResultReturn = JsonHelper.DeserializeObject<PayResultReturn>(responseBody);
                                if (payResultReturn != null && payResultReturn.return_code == "SUCCESS")
                                {
                                    WechatPayData resultData = new WechatPayData(key, signType);
                                    resultData.FromXml(responseBody);
                                    var isSign = resultData.CheckSign();
                                    if (isSign)
                                    {
                                        var payResultCode = JsonHelper.DeserializeObject<PayResultCode>(responseBody);
                                        if (payResultCode != null && payResultCode.result_code == "SUCCESS")
                                        {
                                            var payResultBase = JsonHelper.DeserializeObject<PayResultBase>(responseBody);
                                            if (payResultBase != null)
                                            {
                                                /*
                                                支付类型为  
                                                JSAPI 公众号支付
                                                NATIVE Native支付
                                                APP APP支付 
                                                MWEB H5支付
                                                MICROPAY 扫码支付 
                                                */
                                                switch (payResultBase.trade_type)
                                                {
                                                    case "JSAPI":
                                                        return JsonHelper.DeserializeObject<OrderResultJsApi>(responseBody);
                                                    case "NATIVE":
                                                        return JsonHelper.DeserializeObject<OrderResultNative>(responseBody);
                                                    case "APP":
                                                        return JsonHelper.DeserializeObject<PayResultApp>(responseBody);
                                                    case "MWEB":
                                                        return JsonHelper.DeserializeObject<OrderResultH5>(responseBody);
                                                    case "MICROPAY":
                                                        return JsonHelper.DeserializeObject<OrderResultMicropay>(responseBody);
                                                }
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }

        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public OrderQueryResult? OrderQuery(OrderQueryRequest request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.transaction_id))
                        {
                            param.Add("transaction_id", request.transaction_id);
                        }
                        else
                        {
                            if (!string.IsNullOrWhiteSpace(request.out_trade_no))
                            {
                                param.Add("out_trade_no", request.out_trade_no);
                            }
                        }
                        string sign_type = "";
                        if (signType == PaySignType.HMACSHA256)
                        {
                            sign_type = "HMAC-SHA256";
                        }
                        else
                        {
                            sign_type = "MD5";
                        }
                        if (!string.IsNullOrWhiteSpace(sign_type))
                        {
                            param.Add("sign_type", sign_type);
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        var response = wechatMchService.SendRequest(HttpMethod.Post, "pay/orderquery", param, "", null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var payResultReturn = JsonHelper.DeserializeObject<PayResultReturn>(responseBody);
                                if (payResultReturn != null && payResultReturn.return_code == "SUCCESS")
                                {
                                    WechatPayData resultData = new WechatPayData(key, signType);
                                    resultData.FromXml(responseBody);
                                    var isSign = resultData.CheckSign();
                                    if (isSign)
                                    {
                                        var payResultCode = JsonHelper.DeserializeObject<PayResultCode>(responseBody);
                                        if (payResultCode != null && payResultCode.result_code == "SUCCESS")
                                        {
                                            var orderQueryResult = JsonHelper.DeserializeObject<OrderQueryResult>(responseBody);
                                            if (orderQueryResult != null)
                                            {
                                                List<CouponInfo> coupon_list = new List<CouponInfo>();
                                                var index = 0;
                                                var isExist = true;
                                                while (isExist)
                                                {
                                                    /*
                                                    代金券ID	coupon_id_$n
                                                    代金券类型	coupon_type_$n
                                                    单个代金券金额	coupon_fee_$n
                                                    微信支付订单号	transaction_id
                                                    */
                                                    isExist = resultData.IsSet($"coupon_id_{index}");
                                                    if (isExist)
                                                    {
                                                        string coupon_id = string.Empty;
                                                        var coupon_id_str = resultData.GetValue($"coupon_id_{index}")?.ToString();
                                                        if (!string.IsNullOrWhiteSpace(coupon_id_str))
                                                        {
                                                            coupon_id = coupon_id_str;
                                                        }
                                                        string coupon_type = string.Empty;
                                                        var coupon_type_str = resultData.GetValue($"coupon_type_{index}")?.ToString();
                                                        if (!string.IsNullOrWhiteSpace(coupon_type_str))
                                                        {
                                                            coupon_type = coupon_type_str;
                                                        }

                                                        coupon_list.Add(new CouponInfo()
                                                        {
                                                            coupon_id = coupon_id,
                                                            coupon_type = coupon_type,
                                                            coupon_fee = Convert.ToInt64(resultData.GetValue($"coupon_type_{index}"))
                                                        });
                                                    }
                                                    else
                                                    {
                                                        break;
                                                    }
                                                    index++;
                                                }
                                                orderQueryResult.coupon_list = coupon_list;

                                                return orderQueryResult;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }

        /// <summary>
        /// 关闭订单
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public OrderCloseResult? OrderClose(OrderCloseRequest request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.out_trade_no))
                        {
                            param.Add("out_trade_no", request.out_trade_no);
                        }
                        string sign_type = "";
                        if (signType == PaySignType.HMACSHA256)
                        {
                            sign_type = "HMAC-SHA256";
                        }
                        else
                        {
                            sign_type = "MD5";
                        }
                        if (!string.IsNullOrWhiteSpace(sign_type))
                        {
                            param.Add("sign_type", sign_type);
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        var response = wechatMchService.SendRequest(HttpMethod.Post, "pay/closeorder", param, "", null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var payResultReturn = JsonHelper.DeserializeObject<PayResultReturn>(responseBody);
                                if (payResultReturn != null && payResultReturn.return_code == "SUCCESS")
                                {
                                    WechatPayData resultData = new WechatPayData(key, signType);
                                    resultData.FromXml(responseBody);
                                    var isSign = resultData.CheckSign();
                                    if (isSign)
                                    {
                                        var payResultCode = JsonHelper.DeserializeObject<PayResultCode>(responseBody);
                                        if (payResultCode != null && payResultCode.result_code == "SUCCESS")
                                        {
                                            var orderCloseResult = JsonHelper.DeserializeObject<OrderCloseResult>(responseBody);
                                            if (orderCloseResult != null)
                                            {
                                                return orderCloseResult;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }

        #region MICROPAY 扫码支付 专用方法
        /// <summary>
        /// 撤销订单
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public OrderReverseResult? OrderReverse(OrderReverseRequest request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.transaction_id))
                        {
                            param.Add("transaction_id", request.transaction_id);
                        }
                        else
                        {
                            if (!string.IsNullOrWhiteSpace(request.out_trade_no))
                            {
                                param.Add("out_trade_no", request.out_trade_no);
                            }
                        }
                        string sign_type = "";
                        if (signType == PaySignType.HMACSHA256)
                        {
                            sign_type = "HMAC-SHA256";
                        }
                        else
                        {
                            sign_type = "MD5";
                        }
                        if (!string.IsNullOrWhiteSpace(sign_type))
                        {
                            param.Add("sign_type", sign_type);
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        var response = wechatMchService.SendRequest(HttpMethod.Post, "pay/orderquery", param, "", null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var payResultReturn = JsonHelper.DeserializeObject<PayResultReturn>(responseBody);
                                if (payResultReturn != null && payResultReturn.return_code == "SUCCESS")
                                {
                                    WechatPayData resultData = new WechatPayData(key, signType);
                                    resultData.FromXml(responseBody);
                                    var isSign = resultData.CheckSign();
                                    if (isSign)
                                    {
                                        var payResultCode = JsonHelper.DeserializeObject<PayResultCode>(responseBody);
                                        if (payResultCode != null && payResultCode.result_code == "SUCCESS")
                                        {
                                            var orderReverseResult = JsonHelper.DeserializeObject<OrderReverseResult>(responseBody);
                                            if (orderReverseResult != null)
                                            {
                                                return orderReverseResult;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }
        #endregion MICROPAY 扫码支付 专用方法

        /// <summary>
        /// 申请退款
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public PayRefundResult? PayRefund(PayRefundRequest request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.transaction_id))
                        {
                            param.Add("transaction_id", request.transaction_id);
                        }
                        else
                        {
                            if (!string.IsNullOrWhiteSpace(request.out_trade_no))
                            {
                                param.Add("out_trade_no", request.out_trade_no);
                            }
                        }
                        if (!string.IsNullOrWhiteSpace(request.out_refund_no))
                        {
                            param.Add("out_refund_no", request.out_refund_no);
                        }
                        param.Add("total_fee", request.total_fee);
                        param.Add("refund_fee", request.refund_fee);
                        if (!string.IsNullOrWhiteSpace(request.refund_fee_type))
                        {
                            param.Add("refund_fee_type", request.refund_fee_type);
                        }
                        if (!string.IsNullOrWhiteSpace(request.refund_desc))
                        {
                            param.Add("refund_desc", request.refund_desc);
                        }
                        if (!string.IsNullOrWhiteSpace(request.refund_account))
                        {
                            param.Add("refund_account", request.refund_account);
                        }
                        if (!string.IsNullOrWhiteSpace(request.notify_url))
                        {
                            param.Add("notify_url", request.notify_url);
                        }

                        string sign_type = "";
                        if (signType == PaySignType.HMACSHA256)
                        {
                            sign_type = "HMAC-SHA256";
                        }
                        else
                        {
                            sign_type = "MD5";
                        }
                        if (!string.IsNullOrWhiteSpace(sign_type))
                        {
                            param.Add("sign_type", sign_type);
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        var response = wechatMchService.SendRequest(HttpMethod.Post, "secapi/pay/refund", param, request.mch_id, null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var payResultReturn = JsonHelper.DeserializeObject<PayResultReturn>(responseBody);
                                if (payResultReturn != null && payResultReturn.return_code == "SUCCESS")
                                {
                                    WechatPayData resultData = new WechatPayData(key, signType);
                                    resultData.FromXml(responseBody);
                                    var isSign = resultData.CheckSign();
                                    if (isSign)
                                    {
                                        var payResultCode = JsonHelper.DeserializeObject<PayResultCode>(responseBody);
                                        if (payResultCode != null && payResultCode.result_code == "SUCCESS")
                                        {
                                            var payRefundResult = JsonHelper.DeserializeObject<PayRefundResult>(responseBody);
                                            if (payRefundResult != null)
                                            {
                                                List<CouponInfo> coupon_list = new List<CouponInfo>();
                                                var index = 0;
                                                var isExist = true;
                                                while (isExist)
                                                {
                                                    /*
                                                    代金券ID	coupon_id_$n
                                                    代金券类型	coupon_type_$n
                                                    单个代金券金额	coupon_fee_$n
                                                    微信支付订单号	transaction_id
                                                    */
                                                    isExist = resultData.IsSet($"coupon_id_{index}");
                                                    if (isExist)
                                                    {
                                                        string coupon_id = string.Empty;
                                                        var coupon_id_str = resultData.GetValue($"coupon_id_{index}")?.ToString();
                                                        if (!string.IsNullOrWhiteSpace(coupon_id_str))
                                                        {
                                                            coupon_id = coupon_id_str;
                                                        }
                                                        string coupon_type = string.Empty;
                                                        var coupon_type_str = resultData.GetValue($"coupon_type_{index}")?.ToString();
                                                        if (!string.IsNullOrWhiteSpace(coupon_type_str))
                                                        {
                                                            coupon_type = coupon_type_str;
                                                        }

                                                        coupon_list.Add(new CouponInfo()
                                                        {
                                                            coupon_id = coupon_id,
                                                            coupon_type = coupon_type,
                                                            coupon_fee = Convert.ToInt64(resultData.GetValue($"coupon_type_{index}"))
                                                        });
                                                    }
                                                    else
                                                    {
                                                        break;
                                                    }
                                                    index++;
                                                }
                                                payRefundResult.coupon_list = coupon_list;

                                                return payRefundResult;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }

        /// <summary>
        /// 退款查询（未完成）
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public RefundQueryResult? RefundQuery(RefundQueryRequest request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.transaction_id))
                        {
                            param.Add("transaction_id", request.transaction_id);
                        }
                        else
                        {
                            if (!string.IsNullOrWhiteSpace(request.out_trade_no))
                            {
                                param.Add("out_trade_no", request.out_trade_no);
                            }
                        }
                        string sign_type = "";
                        if (signType == PaySignType.HMACSHA256)
                        {
                            sign_type = "HMAC-SHA256";
                        }
                        else
                        {
                            sign_type = "MD5";
                        }
                        if (!string.IsNullOrWhiteSpace(sign_type))
                        {
                            param.Add("sign_type", sign_type);
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        var response = wechatMchService.SendRequest(HttpMethod.Post, "pay/refundquery", param, "", null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var payResultReturn = JsonHelper.DeserializeObject<PayResultReturn>(responseBody);
                                if (payResultReturn != null && payResultReturn.return_code == "SUCCESS")
                                {
                                    WechatPayData resultData = new WechatPayData(key, signType);
                                    resultData.FromXml(responseBody);
                                    var isSign = resultData.CheckSign();
                                    if (isSign)
                                    {
                                        var payResultCode = JsonHelper.DeserializeObject<PayResultCode>(responseBody);
                                        if (payResultCode != null && payResultCode.result_code == "SUCCESS")
                                        {
                                            var refundQueryResult = JsonHelper.DeserializeObject<RefundQueryResult>(responseBody);
                                            if (refundQueryResult != null)
                                            {


                                                return refundQueryResult;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }

        /// <summary>
        /// 下载对账单（未完成）
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="key">微信支付V2密钥</param>
        /// <param name="signType">（HMAC-SHA256和MD5，默认为MD5）</param>
        /// <returns></returns>
        public DownloadBillResult? DownloadBill(DownloadBillRequest request, string key, PaySignType signType = PaySignType.MD5)
        {
            try
            {
                if (wechatMchService != null)
                {
                    Dictionary<string, object> param = new Dictionary<string, object>();
                    if (request != null)
                    {
                        #region 请求参数
                        if (!string.IsNullOrWhiteSpace(request.appid))
                        {
                            param.Add("appid", request.appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.mch_id))
                        {
                            param.Add("mch_id", request.mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_appid))
                        {
                            param.Add("sub_appid", request.sub_appid);
                        }
                        if (!string.IsNullOrWhiteSpace(request.sub_mch_id))
                        {
                            param.Add("sub_mch_id", request.sub_mch_id);
                        }
                        if (!string.IsNullOrWhiteSpace(request.device_info))
                        {
                            param.Add("device_info", request.device_info);
                        }
                        if (!string.IsNullOrWhiteSpace(request.bill_date))
                        {
                            param.Add("bill_date", request.bill_date);
                        }
                        if (!string.IsNullOrWhiteSpace(request.bill_type))
                        {
                            param.Add("bill_type", request.bill_type);
                        }
                        if (!string.IsNullOrWhiteSpace(request.tar_type))
                        {
                            param.Add("tar_type", request.tar_type);
                        }

                        string sign_type = "";
                        if (signType == PaySignType.HMACSHA256)
                        {
                            sign_type = "HMAC-SHA256";
                        }
                        else
                        {
                            sign_type = "MD5";
                        }
                        if (!string.IsNullOrWhiteSpace(sign_type))
                        {
                            param.Add("sign_type", sign_type);
                        }

                        param.Add("nonce_str", StringHelper.GenerateNonceStr());

                        #region 生成签名
                        WechatPayData requestData = new WechatPayData(key, signType);
                        foreach (var item in param)
                        {
                            requestData.SetValue(item.Key, item.Value);
                        }
                        string sign = requestData.CreateSign();

                        if (!string.IsNullOrWhiteSpace(sign))
                        {
                            param.Add("sign", sign);
                        }
                        #endregion 生成签名
                        #endregion  请求参数

                        var response = wechatMchService.SendRequest(HttpMethod.Post, "pay/downloadbill", param, "", null, "application/xml");
                        HttpClientResponse httpClientResponse = new HttpClientResponse(response);
                        httpClientResponse.GetResponseBody();
                        if (httpClientResponse.IsResponse)
                        {
                            var responseBody = httpClientResponse.ResponseBody;
                            if (!string.IsNullOrWhiteSpace(responseBody))
                            {
                                var downloadBillResult = JsonHelper.DeserializeObject<DownloadBillResult>(responseBody);
                                if (downloadBillResult != null && downloadBillResult.return_code == "FAIL")
                                {
                                    return new DownloadBillResult()
                                    {
                                        return_code = downloadBillResult.return_code,
                                        return_msg = downloadBillResult.return_msg,
                                        err_code = downloadBillResult.err_code
                                    };
                                }
                            }
                            else
                            {
                                var responseBytes = httpClientResponse.ResponseBytes;
                                if (responseBytes != null)
                                {
                                    return new DownloadBillResult()
                                    {
                                        return_code = "SUCCESS",
                                        file_bytes = responseBytes
                                    };
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex.ToString());
            }
            return default;
        }
    }
}
